import json
import logging


class MultiMediaServer(object):
    def __init__(self, client):
        self.mqttc = client

        self.audio_on = None
        self.audio_off = None
        self.video_on = None
        self.video_off = None
        self.file_req = None
        self.file_rec = None

    def on_message(self, message):
        try:
            string = str(bytes(message.payload), "utf-8")
            isstring = True
        except:
            isstring = False
        if isstring and string[0] == "{" and string[-1] == "}":
            data = json.loads(str(bytes(message.payload), "utf-8"))
            if data['type'] == 'ctrl':
                if data['device'] == 'audio':
                    if data['action'] == 'on':
                        self.client_topic = "/" + \
                            data['user_id'] + "/" + data['session']
                        self.audio_on(data)
                    elif data['action'] == 'off':
                        self.audio_off(data)
                    return True
                elif data['device'] == 'video':
                    if data['action'] == 'on':
                        self.client_topic = "/" + \
                            data['user_id'] + "/" + data['session']
                        self.video_on(data)
                    elif data['action'] == 'off':
                        self.video_off(data)
                    return True
                elif data['device'] == 'file':
                    if data['action'] == 'req':
                        self.filename=data['filename']
                        self.client_topic = "/" + \
                            data['user_id'] + "/" + data['session']
                        self.file_req(data['user_id'],data['session'])
                    return True
                else:
                    return False
            else:
                return False
        else:
            if message.topic.split("/")[-1]=='file':
                self.file_rec(message.payload,self.filename)
                return True
            else:
                return False

    def file_ack(self, topic):
        payload = DeviceCtrl.file_ack(
            self.mqttc.user_id, self.mqttc.session, topic)
        self.mqttc.publish(self.client_topic, payload, qos=2)
        logging.debug("file_ack")
        logging.debug(self.client_topic)
        logging.debug(payload)


class MultiMediaClient(object):
    def __init__(self, client):
        self.mqttc = client
        self.audio_channel = None
        self.audio_play = None
        self.audio_using = False
        self.video_channel = None
        self.video_play = None
        self.file_send = None
        self.video_using = False

    def on_message(self, message):
        try:
            string = str(bytes(message.payload), "utf-8")
            isstring = True
        except:
            isstring = False
        if isstring and string[0] == "{" and string[-1] == "}":
            data = json.loads(str(bytes(message.payload), "utf-8"))
            if data['type'] == 'ctrl':
                if data['device'] == 'file':
                    if data['action'] == 'ack':
                        self.file_send(data)
                        return True
                    else:
                        return False
                else:
                    return False
            else:
                return False
        else:
            channel = message.topic.split("/")[-1]
            if channel == self.audio_channel:
                if not self.audio_using:
                    return True
                self.audio_play(message.payload)
                return True
            elif channel == self.video_channel:
                if not self.video_using:
                    return True
                self.video_play(message.payload)
                return True
            else:
                return False

    def audio_on(self, user_id, user_session, channel):
        self.audio_channel = channel
        self.audio_ctrl_topic = "/" + user_id + "/" + user_session
        payload = DeviceCtrl.audio_on(
            self.mqttc.user_id, self.mqttc.session, channel)
        self.mqttc.subscribe(self.mqttc.user_topic_root)
        self.mqttc.publish(self.audio_ctrl_topic, payload, qos=2)
        logging.debug("audio_on")
        logging.debug(self.audio_ctrl_topic)
        logging.debug(payload)

    def audio_off(self):
        payload = DeviceCtrl.audio_off()
        self.mqttc.publish(self.audio_ctrl_topic, payload, qos=2)
        logging.debug("audio_off")
        logging.debug(self.audio_ctrl_topic)
        logging.debug(payload)

    def video_on(self, user_id, user_session, channel):
        self.video_channel = channel
        self.video_ctrl_topic = "/" + user_id + "/" + user_session
        payload = DeviceCtrl.video_on(
            self.mqttc.user_id, self.mqttc.session, channel)
        self.mqttc.subscribe(self.mqttc.user_topic_root)
        self.mqttc.publish(self.video_ctrl_topic, payload, qos=2)
        logging.debug("video_on")
        logging.debug(self.video_ctrl_topic)
        logging.debug(payload)

    def video_off(self):
        payload = DeviceCtrl.video_off()
        self.mqttc.publish(self.video_ctrl_topic, payload, qos=2)
        logging.debug("video_off")
        logging.debug(self.video_ctrl_topic)
        logging.debug(payload)

    def file_req(self, user_id, session, filename):
        payload = DeviceCtrl.file_req(self.mqttc.user_id, self.mqttc.session, filename)
        self.filetopic = "/" + user_id + "/" + session
        self.mqttc.publish(self.filetopic, payload, qos=2)
        logging.debug("file_req")
        logging.debug(self.filetopic)
        logging.debug(payload)


class DeviceCtrl(object):
    def audio_on(user_id, session, channel):
        data = {
            'type': 'ctrl',
            'device': 'audio',
            'action': 'on',
            'user_id': user_id,
            'session': session,
            'channel': channel
        }
        return json.dumps(data)

    def audio_off():
        data = {
            'type': 'ctrl',
            'device': 'audio',
            'action': 'off'
        }
        return json.dumps(data)

    def video_on(user_id, session, channel):
        data = {
            'type': 'ctrl',
            'device': 'video',
            'action': 'on',
            'user_id': user_id,
            'session': session,
            'channel': channel
        }
        return json.dumps(data)

    def video_off():
        data = {
            'type': 'ctrl',
            'device': 'video',
            'action': 'off'
        }
        return json.dumps(data)

    def file_req(user_id, session, filename):
        data = {
            'type': 'ctrl',
            'device': 'file',
            'action': 'req',
            'user_id': user_id,
            'session': session,
            'filename': filename
        }
        return json.dumps(data)

    def file_ack(user_id, session, topic):
        data = {
            'type': 'ctrl',
            'device': 'file',
            'action': 'ack',
            'user_id': user_id,
            'session': session,
            'topic': topic
        }
        return json.dumps(data)
